package com.xc.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xc.common.Const;
import com.xc.common.ServerResponse;
import com.xc.dao.AgentUserMapper;
import com.xc.dao.UserCashDetailMapper;
import com.xc.dao.UserMapper;
import com.xc.dao.UserRechargeMapper;
import com.xc.pojo.*;
import com.xc.service.*;
import com.xc.utils.DateTimeUtil;
import com.xc.utils.KeyUtils;
import com.xc.utils.email.SendHTMLMail;
import com.xc.utils.redis.JsonUtil;
import com.xc.utils.redis.RedisConst;
import com.xc.utils.redis.RedisShardedPoolUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

/**
 * @author mipha
 * @version 1.0
 * @date 2019/2/16 3:05 PM
 */
@Service("iUserRechargeService")
@Slf4j
public class UserRechargeServiceImpl implements IUserRechargeService {

    @Autowired
    UserRechargeMapper userRechargeMapper;
    @Autowired
    IUserService iUserService;
    @Autowired
    UserMapper userMapper;
    @Autowired
    IAgentUserService iAgentUserService;
    @Autowired
    AgentUserMapper agentUserMapper;
    @Autowired
    ISiteSettingService iSiteSettingService;
    @Autowired
    UserCashDetailMapper userCashDetailMapper;
    @Autowired
    ISiteInfoService iSiteInfoService;

    @Override
    public ServerResponse checkInMoney(int maxOrder,Integer userId) {

        int count = userRechargeMapper.checkInMoney(Const.UserRechargeStatus.apply_status,userId);

        if(count > maxOrder){
            return ServerResponse.createByErrorMsg("一小时内只能发起" + maxOrder + "次入金");
        }else{
            return ServerResponse.createBySuccess();
        }
    }

    @Override
    public ServerResponse inMoney(String amt, String payType, HttpServletRequest request) {

        if(StringUtils.isBlank(amt) || StringUtils.isBlank(payType)) {
            return ServerResponse.createByErrorMsg("参数不能为空");
        }

        SiteSetting siteSetting = iSiteSettingService.getSiteSetting();
        if(siteSetting == null){
            return ServerResponse.createByErrorMsg("设置set未初始化");
        }
        if(new BigDecimal(siteSetting.getChargeMinAmt()+"").compareTo(new BigDecimal(amt)) == 1){
            return ServerResponse.createByErrorMsg("充值金额不得低于"+siteSetting.getChargeMinAmt()+"元");
        }

        //  siteinfo中 收发邮件是否设置
        SiteInfo siteInfo = null;
        ServerResponse serverResponseInfo = iSiteInfoService.getInfo();
        if(serverResponseInfo.isSuccess()){
            siteInfo = (SiteInfo)serverResponseInfo.getData();
            if(StringUtils.isBlank(siteInfo.getSiteHost())
                    || StringUtils.isBlank(siteInfo.getSiteEmailTo())
                    ){
                return ServerResponse.createByErrorMsg("请先设置Host and ToEmail");
            }
        }else{
            return serverResponseInfo;
        }

        User user = iUserService.getCurrentRefreshUser(request);
        if(user.getIsActive() != Const.UserActiveStatus.success_active){
            return ServerResponse.createByErrorMsg("未实名认证不能发起充值");
        }

        //  一小时内 一个用户 只能发起 10次 充值请求
        ServerResponse serverResponse = checkInMoney(10,user.getId());
        if(!serverResponse.isSuccess()){
            return serverResponse;
        }

        //  保存充值记录
        UserRecharge userRecharge = new UserRecharge();

        userRecharge.setUserId(user.getId());
        userRecharge.setNickName(user.getRealName());
        userRecharge.setAgentId(user.getAgentId());

        String ordersn = KeyUtils.getRechargeOrderSn();
        userRecharge.setOrderSn(ordersn);

        userRecharge.setPayChannel(payType);
        userRecharge.setPayAmt(new BigDecimal(amt));
        userRecharge.setOrderStatus(Const.UserRechargeStatus.apply_status);
        userRecharge.setAddTime(new Date());

        int insertCount = userRechargeMapper.insert(userRecharge);
        if(insertCount > 0){
            //  保存订单成功，生成一个 5 分钟有效期的token，保存到redis中
            String email_token = KeyUtils.getUniqueKey();
            String redisSetExResult = RedisShardedPoolUtils
                    .setEx(email_token , email_token
                            , RedisConst.RedisCacheExTime.REDIS_EMAIL_TOKEN_EXTIME);
            log.info("用户充值，保存redis token成功，redisSetExResult = {}" , redisSetExResult);
            //  发送审核邮件
            SendHTMLMail.send(user,userRecharge,email_token
                    ,siteInfo.getSiteHost(),siteInfo.getSiteEmailTo());
            log.info("用户充值，发送审核邮件成功");
            return ServerResponse.createBySuccessMsg("创建支付订单成功！");
        }else{
            return ServerResponse.createByErrorMsg("创建支付订单失败");
        }
    }

    @Override
    public ServerResponse findUserRechargeByOrderSn(String orderSn) {

        UserRecharge userRecharge = userRechargeMapper.findUserRechargeByOrderSn(orderSn);
        if(userRecharge != null){
            return ServerResponse.createBySuccess(userRecharge);
        }else{
            return ServerResponse.createByErrorMsg("找不到充值订单");
        }
    }

    @Override
    @Transactional
    public ServerResponse chargeSuccess(UserRecharge userRecharge) throws Exception{

        log.info("充值订单 确认成功操作 id = {}" , userRecharge.getId());

        if(userRecharge.getOrderStatus() != Const.UserRechargeStatus.apply_status){
            return ServerResponse.createByErrorMsg("订单状态不能重复修改");
        }

        //  1.  修改用户资金
        User user = userMapper.selectByPrimaryKey(userRecharge.getUserId());
        if(user == null){
            return ServerResponse.createByErrorMsg("用户不存在");
        }
        BigDecimal userAmt_before = user.getUserAmt();
        BigDecimal enableAmt_before = user.getEnableAmt();
        user.setUserAmt(userAmt_before.add(userRecharge.getPayAmt()));
        user.setEnableAmt(enableAmt_before.add(userRecharge.getPayAmt()));
        int updateCount = userMapper.updateByPrimaryKeySelective(user);
        if(updateCount > 0){
            log.info("1.修改用户资金成功");
        }else{
            return ServerResponse.createByErrorMsg("失败，修改用户资金失败");
        }

        //  2.  修改订单状态
        userRecharge.setOrderStatus(Const.UserRechargeStatus.charge_success);
        userRecharge.setPayTime(new Date());
        int updateCCount = userRechargeMapper.updateByPrimaryKeySelective(userRecharge);
        if(updateCCount  > 0){
            log.info("2.修改订单状态成功");
        }else{
            throw new Exception("2. 修改订单状态失败!");
        }

        //  3.  保存资金明细
        UserCashDetail ucd = new UserCashDetail();
        ucd.setAgentId(user.getAgentId());
        ucd.setAgentName(user.getAgentName());
        ucd.setUserId(user.getId());
        ucd.setUserName(user.getRealName());
        ucd.setDeType(Const.UserCashDetailType.usercz);
        ucd.setDeAmt(userRecharge.getPayAmt());
        ucd.setDeSummary("用户充值成功，充值前总金额:"+userAmt_before + ",充值后总金额:"+user.getUserAmt()
                +",充值前可用:"+enableAmt_before+",充值后可用:"+user.getEnableAmt()
        );
        ucd.setAddTime(new Date());
        ucd.setIsRead(Const.UserCashDetailIsRead.no_read);
        int insertCount = userCashDetailMapper.insert(ucd);
        if(insertCount > 0){
            return ServerResponse.createBySuccessMsg("充值成功！");
        }else{
            return ServerResponse.createByErrorMsg("充值失败");
        }

    }

    @Override
    public ServerResponse chargeFail(UserRecharge userRecharge) throws Exception {

        if(userRecharge.getOrderStatus() != Const.UserRechargeStatus.apply_status){
            return ServerResponse.createByErrorMsg("订单状态不能重复修改");
        }

        userRecharge.setOrderStatus(Const.UserRechargeStatus.charge_fail);
        int updateCCount = userRechargeMapper.updateByPrimaryKeySelective(userRecharge);
        if(updateCCount  > 0){
            return ServerResponse.createBySuccessMsg("订单已修改为失败");
        }else{
            return ServerResponse.createByErrorMsg("修改出现异常");
        }
    }

    @Override
    public ServerResponse chargeCancel(UserRecharge userRecharge) throws Exception {

        if(userRecharge.getOrderStatus() != Const.UserRechargeStatus.apply_status){
            return ServerResponse.createByErrorMsg("订单状态不能重复修改");
        }

        userRecharge.setOrderStatus(Const.UserRechargeStatus.charge_cancel);
        int updateCCount = userRechargeMapper.updateByPrimaryKeySelective(userRecharge);
        if(updateCCount  > 0){
            return ServerResponse.createBySuccessMsg("订单取消成功");
        }else{
            return ServerResponse.createByErrorMsg("订单取消出现异常");
        }
    }

    @Override
    public ServerResponse<PageInfo> findUserChargeList(String payChannel, String orderStatus, HttpServletRequest request, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);

        User user = iUserService.getCurrentUser(request);

        List<UserRecharge> userRecharges = userRechargeMapper
                .findUserChargeList(user.getId(),payChannel,orderStatus);

        PageInfo pageInfo = new PageInfo(userRecharges);

        return ServerResponse.createBySuccess(pageInfo);
    }

    @Override
    public ServerResponse<PageInfo> listByAgent(Integer agentId ,String realName
            , String payChannel, Integer state, HttpServletRequest request, int pageNum, int pageSize) {
        //  当前登陆代理
        AgentUser currentAgent = iAgentUserService.getCurrentAgent(request);

        //  如果传入了agentId,首先判断agentId是否为当前代理下
        if(agentId != null){
            AgentUser agentUser = agentUserMapper.selectByPrimaryKey(agentId);
            if(agentUser.getParentId() != currentAgent.getId()){
                return ServerResponse.createByErrorMsg("不能查询非下级代理记录");
            }
        }
        Integer searchId = null;
        if(agentId == null){
            searchId = currentAgent.getId();    //  如果传入id为空，查询登陆代理的用户
        }else{
            searchId = agentId;
        }


        PageHelper.startPage(pageNum, pageSize);

        List<UserRecharge> userRecharges = userRechargeMapper
                .listByAgent(searchId,realName,payChannel,state);

        PageInfo pageInfo = new PageInfo(userRecharges);

        return ServerResponse.createBySuccess(pageInfo);
    }

    @Override
    public ServerResponse listByAdmin(Integer agentId, Integer userId, String realName
            , Integer state, String beginTime, String endTime
            , HttpServletRequest request, int pageNum, int pageSize) {

        PageHelper.startPage(pageNum, pageSize);

        //  转换日期格式
        Timestamp begin_time = null;
        if(StringUtils.isNotBlank(beginTime)){
            begin_time = DateTimeUtil.searchStrToTimestamp(beginTime);
        }
        Timestamp end_time = null;
        if(StringUtils.isNotBlank(endTime)){
            end_time = DateTimeUtil.searchStrToTimestamp(endTime);
        }

        List<UserRecharge> userRecharges = userRechargeMapper
                .listByAdmin(agentId,userId,realName,state,begin_time,end_time);

        PageInfo pageInfo = new PageInfo(userRecharges);

        return ServerResponse.createBySuccess(pageInfo);
    }

    @Override
    @Transactional
    public ServerResponse updateState(Integer chargeId, Integer state) throws Exception{

        UserRecharge userRecharge = userRechargeMapper.selectByPrimaryKey(chargeId);

        if(userRecharge == null){
            return ServerResponse.createByErrorMsg("充值订单不存在");
        }
        if(userRecharge.getOrderStatus() != Const.UserRechargeStatus.apply_status){
            return ServerResponse.createByErrorMsg("订单状态不是下单状态不能更改");
        }

        //  1.  修改用户资金
        if(state == Const.UserRechargeStatus.charge_success){
            //  如果修改为成功就增加用户资金 失败则不修改
            User user = userMapper.selectByPrimaryKey(userRecharge.getUserId());
            if(user == null){
                return ServerResponse.createByErrorMsg("用户不存在");
            }
            BigDecimal user_amt = user.getUserAmt().add(userRecharge.getPayAmt());
            log.info("管理员确认订单成功，增加用户 {} 总资金，原金额 = {} , 增加后 = {}" , user.getId() , user.getUserAmt() , user_amt);
            user.setUserAmt(user_amt);
            BigDecimal user_enable_amt = user.getEnableAmt().add(userRecharge.getPayAmt());
            log.info("管理员确认订单成功，增加用户 {} 可用资金，原金额 = {} , 增加后 = {}" , user.getId() , user.getEnableAmt() , user_enable_amt);
            user.setEnableAmt(user_enable_amt);

            int updateCount = userMapper.updateByPrimaryKeySelective(user);
            if(updateCount > 0){
                log.info("修改用户资金成功！");
            }else{
                log.error("修改用户资金出错，抛出异常");
                throw new Exception("修改用户资金出错，抛出异常");
            }
        }

        //  2.  修改订单
        userRecharge.setOrderStatus(state == Const.UserRechargeStatus.charge_success
                ? Const.UserRechargeStatus.charge_success
                : Const.UserRechargeStatus.charge_fail);
        userRecharge.setPayTime(new Date());
        int updateCount = userRechargeMapper.updateByPrimaryKeySelective(userRecharge);
        if(updateCount > 0){
            return ServerResponse.createBySuccessMsg("修改订单状态成功！");
        }else{
            return ServerResponse.createByErrorMsg("修改订单状态失败！");
        }
    }

    @Override
    public ServerResponse createOrder(Integer userId, Integer state, Integer amt) {
        if(userId == null || state == null || amt == null){
            return ServerResponse.createByErrorMsg("参数不能为空");
        }

        User user = userMapper.selectByPrimaryKey(userId);
        if(user == null){
            return ServerResponse.createByErrorMsg("找不到用户");
        }

        UserRecharge userRecharge = new UserRecharge();
        userRecharge.setUserId(user.getId());
        userRecharge.setNickName(user.getRealName());
        userRecharge.setAgentId(user.getAgentId());

        String ordersn = KeyUtils.getRechargeOrderSn();
        userRecharge.setOrderSn(ordersn);

        userRecharge.setPayChannel(Const.UserRechargeChannel.alipay_company_trans+"");
        userRecharge.setPayAmt(new BigDecimal(amt));
        userRecharge.setAddTime(new Date());
        userRecharge.setPayTime(new Date());

        if(state == 0){
            userRecharge.setOrderStatus(Const.UserRechargeStatus.apply_status);
        }else if(state == 1){
            userRecharge.setOrderStatus(Const.UserRechargeStatus.charge_success);
            //   这里修改用户的资金
            user.setUserAmt(user.getUserAmt().add(new BigDecimal(amt)));
            user.setEnableAmt(user.getEnableAmt().add(new BigDecimal(amt)));
            userMapper.updateByPrimaryKeySelective(user);
        }else if(state == 2){
            userRecharge.setOrderStatus(Const.UserRechargeStatus.charge_fail);
        }else{
            return ServerResponse.createByErrorMsg("订单状态不正确");
        }

        int insertCount = userRechargeMapper.insert(userRecharge);
        if(insertCount > 0){
            return ServerResponse.createBySuccessMsg("生成订单成功！");
        }else{
            return ServerResponse.createByErrorMsg("生成订单失败，请重试");
        }

    }

    @Override
    public ServerResponse del(Integer cId) {
        if(cId == null){
            return ServerResponse.createByErrorMsg("id不能为空");
        }
        int updateCount = userRechargeMapper.deleteByPrimaryKey(cId);
        if(updateCount > 0){
            return ServerResponse.createBySuccessMsg("删除成功");
        }else{
            return ServerResponse.createByErrorMsg("删除失败");
        }
    }

    @Override
    public BigDecimal CountChargeSumAmt(Integer chargeState) {
        return userRechargeMapper.CountChargeSumAmt(chargeState);
    }


}
